﻿using Mapster;
using Service.Auth.Domain.AggregatesModel;
using Service.Auth.Model.Model.Dto;
using Service.Auth.Model.Model.QueryDto;
using Service.Core.Identity.Login;
using Service.Core.Repository;
using Service.Framework;
using Service.Framework.Packet;
using Service.Framework.Utils;
using SqlSugar;

namespace Service.Auth.Api.Application.Query;

/// <summary>
/// 角色查询器
/// </summary>
/// <param name="roleRepository"></param>
/// <param name="loginUserSession"></param>
public class RoleQueryService(IRepository<Role> roleRepository, ILoginUserSession loginUserSession) : IScopedService
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<PagedList<RoleDto>> QueryRolePage(QueryRolePageModel request)
    {
        var userInfo = loginUserSession.UserInfo;
        RefAsync<int> totalCount = 0;
        var exp = Expressionable.Create<Role>().And(s => s.Level <= userInfo.RoleMaxLevel)
            .AndIF(!request.RoleName.IsNullOrEmpty(), s => s.RoleName.Contains(request.RoleName))
            .AndIF(!request.RoleNum.IsNullOrEmpty(), s => s.RoleNum.Contains(request.RoleNum));

        var result = await roleRepository.Db.Queryable<Role>().Where(exp.ToExpression()).OrderByDescending(s => s.Level)
      .Includes(x => x.System).ToPageListAsync(request.PageIndex, request.PageSize, totalCount);
        return new PagedList<RoleDto>(result.Adapt<List<RoleDto>>(), request.PageIndex, request.PageSize, totalCount);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<RoleDto> QueryRoleById(QueryRoleById request)
    {
        var result = await roleRepository.Db.Queryable<Role>()
            .Where(s => s.Id.Equals(request.Id))
             .Includes(x => x.System).FirstAsync();
        return result.Adapt<RoleDto>();

    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    public async Task<List<Role>> QueryRoleByIds(List<long> ids)
    {
        return await roleRepository.GetListAsync(s => ids.Contains(s.Id));

    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<Dictionary<long, List<IdName<long, string>>>> QueryRoleDropDown(QueryRoleDropDown request)
    {
        var userInfo = loginUserSession.UserInfo;
        var datas = await roleRepository.Db.Queryable<Role>()
            .WhereIF(request.SystemId.HasValue, s => s.SystemId == request.SystemId)
            .Where(s => s.Level < userInfo.RoleMaxLevel)
            .OrderByDescending(s => s.Level)
            .ToListAsync();
        var result = datas.GroupBy(s => s.SystemId).ToDictionary(s => s.Key, s => s.Select(s => new IdName<long, string>(s.Id, s.RoleNum)).ToList());
        return result;
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="systemId"></param>
    /// <param name="level"></param>
    /// <returns></returns>
    public async Task<List<IdName<string, string>>> QueryRoleDropDownBySystemId(long systemId, int level)
    {
        return await roleRepository.Db.Queryable<Role>().Where(s => s.SystemId.Equals(systemId) && s.Level < level)
            .OrderByDescending(s => s.Level)
            .Select(s => new IdName<string, string>()
            {
                Id = s.RoleNum,
                Value = s.RoleName
            }).ToListAsync();

    }
}